package com.xinsoft.utils;

import cn.hutool.core.util.ObjectUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.xinsoft.constant.Const;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.List;


@Component
@Slf4j
public class JWTUtil {

    private static JWTUtil jwtUtil;

    @PostConstruct
    public void init() {
        jwtUtil = this;
    }

    public static boolean verify(String token) {
        try {
            String secret = Const.SECRET_KEY;
            DecodedJWT jwt = JWT.decode(token);
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer("www.xinsoft.com")
                    .build();
            DecodedJWT verifyJWT = verifier.verify(token);


//            String sign = JWT.create().withHeader(map) //header  这个不设置也可以
//                    .withClaim("userId", 12)//payload 存储非敏感的信息 例如用户账号，不能存密码，防止被人解析
//                    .withExpiresAt(date)//指定令牌的过期时间
//                    .sign(Algorithm.HMAC256("!we2123")) ;//签名  保密复杂
//            System.out.println(sign); //输出结果



            return true;
        } catch (Exception exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static SysUser getSysUser(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            SysUser user = new SysUser();
            user.setId(jwt.getClaim("userId").asInt());
            user.setUsername(jwt.getClaim("sub").asString());
            user.setRealName(jwt.getClaim("realName").asString());
            user.setDeptId(jwt.getClaim("deptId").asInt());
            user.setClerkId(ObjectUtil.isEmpty(jwt.getClaim("clerkId")) ? null : jwt.getClaim("clerkId").asInt());
            return user;
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户真实姓名
     */
    public static String getRealName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("realName").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户ID
     */
    public static Integer getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的用户deptId
     */
    public static Integer getDeptId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("deptId").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static Integer getAllianceId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("allianceId").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }
    /**
     * 获得token中的信息无需secret解密也能获得
     *
     * @return token中包含的公司ID
     */
    public static String getPlatform(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            List<String> audienceList = jwt.getAudience();
            String aud = "";
            if (audienceList != null && audienceList.size() > 0) {
                aud = audienceList.get(0);
            } else {
                return null;
            }
            return aud;
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static Integer getCompanyID(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("companyID").asInt();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static String getCompanyName(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("companyName").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static TokenInfo getTokenInfo(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            TokenInfo tokenInfo = new TokenInfo();
            Integer companyID = jwt.getClaim("companyID").asInt();
            Integer userId = jwt.getClaim("userId").asInt();
            String realName = jwt.getClaim("realName").asString();
            String cellPhone = jwt.getClaim("sub").asString();
            String platform = jwt.getClaim("platform").asString();
            Integer allianceId = jwt.getClaim("allianceId").asInt();
            tokenInfo.setPlatform(platform);
            tokenInfo.setUserId(userId);
            tokenInfo.setCompanyId(companyID);
            tokenInfo.setAllianceId(allianceId);
            tokenInfo.setRealName(realName);
            tokenInfo.setTelephone(cellPhone);
            return tokenInfo;
        } catch (JWTDecodeException e) {
            log.info(e.getMessage());
            return null;
        }
    }

    public static String getTokenFromRequest(HttpServletRequest request) {
        String jwtToken = request.getHeader("Authorization");
        if (StringUtils.startsWithIgnoreCase(jwtToken, "Bearer")) {
            if (jwtToken.length() > 7) {
                jwtToken = jwtToken.substring(7);
            }
        }
        if (StringUtils.isBlank(jwtToken)) {
            jwtToken = request.getHeader("token");
        }
        return jwtToken;
    }

    public static String createToken(TokenInfo tokenInfo) {
        try {
            String secret = tokenInfo.getSecret();
            String platform = tokenInfo.getPlatform();
            String cellPhone = tokenInfo.getTelephone();
            Integer userId = tokenInfo.getUserId();
            String realName = tokenInfo.getRealName();
            Integer companyID = tokenInfo.getCompanyId();
            String companyName = tokenInfo.getCompanyName();
            Integer allianceId = tokenInfo.getAllianceId();
            Algorithm algorithm = Algorithm.HMAC256(secret);
            return JWT.create()
                    .withIssuer("www.ctgoe.com")
                    .withIssuedAt(new Date())
                    .withAudience(platform)
                    .withClaim("username", cellPhone)
                    .withClaim("userId", userId)
                    .withClaim("realName", realName)
                    .withClaim("platform", platform)
                    .withClaim("companyID",companyID)
                    .withClaim("companyName",companyName)
                    .withClaim("allianceId",allianceId)
                    .withClaim("industry",tokenInfo.getIndustry())
                    .withClaim("industryCode",tokenInfo.getIndustryCode())
                    .sign(algorithm);
        } catch (Exception e) {
        }
        return null;
    }

    public static void main(String[] args) throws UnsupportedEncodingException {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhdWQiOiJDVEdfV0VCIiwicmVhbE5hbWUiOiLpu4TmiL_pl7QiLCJpc3MiOiJ3d3cuY3Rnb2UuY29tIiwiaWF0IjoxNTM2MjE2NTU0LCJ1c2VySUQiOjEsInVzZXJuYW1lIjoiMTM1ODQxODgzMjYifQ.7OUGSUJ4Qz12IGVo6T8blWFTU1uGWulcOctN8u61dVw";
        DecodedJWT jwt = JWT.decode(token);

        token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJhbGxpYW5jZUlkIjo4ODg4OTc2ODYsImF1ZCI6IkNUR19VUk0iLCJyZWFsTmFtZSI6IuW8oOaYjOWvjCIsImNvbXBhbnlJRCI6ODg4ODk3NzA3LCJpc3MiOiJ3d3cuY3Rnb2UuY29tIiwiaWF0IjoxNTkzMzA4NjkwLCJ1c2VySUQiOjEzMTAsInBsYXRmb3JtIjoiQ1RHX1VSTSIsInVzZXJuYW1lIjoiMTUyNjE4MDQwMzIiLCJpbmR1c3RyeUNvZGUiOiJDQVJfRElTTUFOVExJTkcifQ.r5WsOQ6g_GKlDlQI0IW_HoiX1KnMoGI56VQcwsXiGM4";
        boolean flag = JWTUtil.verify(token);
        System.out.println(flag);
    }

}
